﻿using Caliburn.Micro;
using SD.Common;
using SD.Infrastructure.DTOBase;
using SD.Infrastructure.WPF.Caliburn.Aspects;
using SD.Infrastructure.WPF.Caliburn.Base;
using SD.Infrastructure.WPF.Extensions;
using SD.IOC.Core.Mediators;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.Extensions;
using System.Threading.Tasks;
using System.Windows;
using SlamDunk.MES.Client.ViewModels.MaterialLot;
using SlamDunk.MES.IAppService.DTOs.Outputs.ResourceContext;
using SlamDunk.MES.IAppService.Interfaces;
using SlamDunk.MES.Presentation.Enums;
using SlamDunk.MES.Presentation.Maps;
using SlamDunk.MES.Presentation.Models.NotifyModels;
using SlamDunk.ValueObjects.Enums;

namespace SlamDunk.MES.Client.ViewModels.StockInOrder
{
    /// <summary>
    /// 单据入库添加明细ViewModel
    /// </summary>
    public class AddItemViewModel : ScreenBase
    {
        #region # 字段及构造器
        /// <summary>
        /// 资源定义服务契约接口代理
        /// </summary>
        private readonly ServiceProxy<IResourceContract> _iResourceContract;

        /// <summary>
        /// 窗口管理器
        /// </summary>
        private readonly IWindowManager _windowManager;
        /// <summary>
        /// 依赖注入构造器
        /// </summary>
        public AddItemViewModel(ServiceProxy<IResourceContract> iResourceContract, IWindowManager windowManager)
        {
            this._iResourceContract = iResourceContract;
            this._windowManager = windowManager;
        }

        #endregion

        #region 属性

        #region 物料定义列表
        /// <summary>
        /// 物料定义列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<MaterialInfo> Materials { get; set; }
        #endregion

        #region 物料批次列表
        /// <summary>
        /// 物料批次列表
        /// </summary>
        [DependencyProperty]
        public IDictionary<string, string> MaterialLots { get; set; }
        #endregion

        #region 供应商列表
        /// <summary>
        /// 供应商列表
        /// </summary>
        [DependencyProperty]
        public ObservableCollection<IdentiferNameNm> Suppliers { get; set; }
        #endregion

        #region 物料批次Id
        /// <summary>
        /// 物料批次Id
        /// </summary>
        [DependencyProperty]
        public Guid? materialLotId { get; set; }
        #endregion

        #region 保质期-天
        /// <summary>
        /// 保质期-天
        /// </summary>
        [DependencyProperty]
        public int GuaranteePeriod { get; set; }
        #endregion

        #region 过期日期
        /// <summary>
        /// 过期日期
        /// </summary>
        [DependencyProperty]
        public DateTime? ExpiredDate { get; set; }
        #endregion

        #region 数量
        /// <summary>
        /// 数量
        /// </summary>
        [DependencyProperty]
        public decimal Quantity { get; set; }
        #endregion

        #region 生产批号
        /// <summary>
        /// 生产批号
        /// </summary>
        [DependencyProperty]
        public string ProductionBatchNo { get; set; }
        #endregion

        #region 规格
        /// <summary>
        /// 规格
        /// </summary>
        [DependencyProperty]
        public string Specification { get; set; }
        #endregion

        #region 物料来源
        /// <summary>
        /// 物料来源
        /// </summary>
        [DependencyProperty]
        public IDictionary<string, string> MaterialSourceTypes { get; set; }
        #endregion

        #region 生产日期
        /// <summary>
        /// 生产日期
        /// </summary>
        [DependencyProperty]
        public DateTime? ProducedDate { get; set; }
        #endregion

        #region 排序
        /// <summary>
        /// 排序
        /// </summary>
        [DependencyProperty]
        public int Sort { get; set; }
        #endregion

        #region 描述
        /// <summary>
        /// 描述
        /// </summary>
        [DependencyProperty]
        public string Description { get; set; }
        #endregion

        #region 已选物料定义 —— MaterialInfo SelectedMaterial
        /// <summary>
        /// 已选物料定义
        /// </summary>
        [DependencyProperty]
        public MaterialInfo SelectedMaterial { get; set; }
        #endregion

        #region 已选批次类型 —— MaterialLotType SelectedMaterialLot
        /// <summary>
        /// 已选批次类型
        /// </summary>
        [DependencyProperty]
        public MaterialLotTypeEnum? SelectedMaterialLot { get; set; }
        #endregion

        #region 已选供应商 —— EnterpriseInfo SelectedSupplier
        /// <summary>
        /// 已选供应商
        /// </summary>
        [DependencyProperty]
        public IdentiferNameNm SelectedSupplier { get; set; }
        #endregion

        #region 已选物料来源 —— EnterpriseInfo SelectedMaterialSourceType
        /// <summary>
        /// 已选物料来源
        /// </summary>
        [DependencyProperty]
        public MaterialSourceType? SelectedMaterialSourceType { get; set; }
        #endregion

        #region 接受日期
        /// <summary>
        /// 接受日期
        /// </summary>
        [DependencyProperty]
        public DateTime? ReceptionDate { get; set; }
        #endregion

        #region 批次类型禁止输入
        /// <summary>
        /// 批次类型禁止输入
        /// </summary>
        [DependencyProperty]
        public bool IsEnabledMaterialLot { get; set; }
        #endregion

        #region 供应商禁止输入
        /// <summary>
        /// 供应商禁止输入
        /// </summary>
        [DependencyProperty]
        public bool IsEnabledSuppliers { get; set; }
        #endregion

        #region 保质期禁止输入
        /// <summary>
        /// 保质期禁止输入
        /// </summary>
        [DependencyProperty]
        public bool IsEnabledGuaranteePeriod { get; set; }
        #endregion

        #region 过期日期禁止输入
        /// <summary>
        /// 过期日期禁止输入
        /// </summary>
        [DependencyProperty]
        public bool IsEnabledExpiredDate { get; set; }
        #endregion

        #region 生产日期禁止输入
        /// <summary>
        /// 生产日期禁止输入
        /// </summary>
        [DependencyProperty]
        public bool IsEnabledProducedDate { get; set; }
        #endregion

        #region 生产批次禁止输入
        /// <summary>
        /// 生产批次禁止输入
        /// </summary>
        [DependencyProperty]
        public bool IsEnabledProductionBatchNo { get; set; }
        #endregion

        #region 规格禁止输入
        /// <summary>
        /// 规格禁止输入
        /// </summary>
        [DependencyProperty]
        public bool IsEnabledSpecification { get; set; }
        #endregion

        #region 物料来源禁止输入
        /// <summary>
        /// 物料来源禁止输入
        /// </summary>
        [DependencyProperty]
        public bool IsEnabledMaterialSourceType { get; set; }
        #endregion

        #region 生产批次禁止输入
        /// <summary>
        /// 生产批次禁止输入
        /// </summary>
        [DependencyProperty]
        public bool IsEnabledReceptionDate { get; set; }
        #endregion

        #region 工厂模型Id
        /// <summary>
        /// 工厂模型Id
        /// </summary>
        [DependencyProperty]
        public Guid? FacilityId { get; set; }
        #endregion
        #endregion

        #region 方法

        #region 加载 —— async Task Load()
        /// <summary>
        /// 加载
        /// </summary>
        public async Task Load(Guid? facility)
        {
            FacilityId = facility;
            this.MaterialSourceTypes = typeof(MaterialSourceType).GetEnumMembers();
            //分页获取物料定义列表
            PageModel<MaterialInfo> MaterialList = await Task.Run(() => this._iResourceContract.Channel.GetMaterialsByPage(
                null,//关键字
                null, //物料来源类型
                null,//是否按批量管理
                FacilityId,//工厂模型Id
                null, //是否启用
                null,//物料类Id
                1,//页码
                int.MaxValue));
            this.Materials = new ObservableCollection<MaterialInfo>(MaterialList.Datas);
            this.MaterialLots = typeof(MaterialLotTypeEnum).GetEnumMembers();
            //初始供应商列表
            PageModel<EnterpriseInfo> Enterprises = await Task.Run(() =>
                this._iResourceContract.Channel.GetEnterprisesByPage(
                   null,//关键字
                   EnterpriseType.Supplier,//企业类型
                   FacilityId,//工厂模型Id
                   1,//页码
                   int.MaxValue)//上级节点Id
             );
            IEnumerable<IdentiferNameNm> EnterpriseModels = Enterprises.Datas.Select(x => x.ToIdentiferName());
            Suppliers = new ObservableCollection<IdentiferNameNm>(EnterpriseModels);
        }
        #endregion

        #region 物料定义选中事件
        /// <summary>
        /// 物料定义选中事件
        /// </summary>
        public async void LoadMaterial()
        {
            if (SelectedMaterial != null)
            {
                IsEnabledMaterialLot = false;
                IsEnabledSuppliers = false;
                IsEnabledGuaranteePeriod = false;
                IsEnabledExpiredDate = false;
                IsEnabledProductionBatchNo = false;
                IsEnabledSpecification = false;
                IsEnabledMaterialSourceType = false;
                IsEnabledProducedDate = false;
                IsEnabledReceptionDate = false;
                if (SelectedMaterial.HasLot)
                {
                    IsEnabledMaterialLot = true;
                    IsEnabledSuppliers = true;
                    IsEnabledGuaranteePeriod = true;
                    IsEnabledExpiredDate = true;
                    IsEnabledProductionBatchNo = true;
                    IsEnabledSpecification = true;
                    IsEnabledMaterialSourceType = true;
                    IsEnabledProducedDate = true;
                    IsEnabledReceptionDate = true;
                }
            }
        }
        #endregion

        #region 批次类型选中事件
        /// <summary>
        /// 批次类型选中事件
        /// </summary>
        public async void LoadMaterialLot()
        {
            if (SelectedMaterialLot == MaterialLotTypeEnum.Old)
            {
                IsEnabledSuppliers = false;
                IsEnabledGuaranteePeriod = false;
                IsEnabledExpiredDate = false;
                IsEnabledProductionBatchNo = false;
                IsEnabledSpecification = false;
                IsEnabledMaterialSourceType = false;
                IsEnabledProducedDate = false;
                IsEnabledReceptionDate = false;
                SelectMaterialLotViewModel viewModel = ResolveMediator.Resolve<SelectMaterialLotViewModel>();
                viewModel.Load(FacilityId, SelectedMaterial.Id);
                bool? result = await this._windowManager.ShowDialogAsync(viewModel);
                if (result == true)
                {
                    SelectedSupplier = Suppliers.Where(x => x.Id == viewModel.SelectedMaterialLot.SupplierId && x.Name == viewModel.SelectedMaterialLot.SupplierName).FirstOrDefault();
                    GuaranteePeriod = viewModel.SelectedMaterialLot.GuaranteePeriod.Days;
                    ExpiredDate = viewModel.SelectedMaterialLot.ExpiredDate;
                    ProductionBatchNo = viewModel.SelectedMaterialLot.ProductionBatchNo;
                    Specification = viewModel.SelectedMaterialLot.Specification;
                    SelectedMaterialSourceType = viewModel.SelectedMaterialLot.MaterialSourceType;
                    ProducedDate = viewModel.SelectedMaterialLot.ProducedDate;
                    materialLotId = viewModel.SelectedMaterialLot.Id;
                }
            }
            else
            {
                if (SelectedMaterial.HasLot)
                {
                    IsEnabledSuppliers = true;
                    IsEnabledGuaranteePeriod = true;
                    IsEnabledExpiredDate = true;
                    IsEnabledProductionBatchNo = true;
                    IsEnabledSpecification = true;
                    IsEnabledMaterialSourceType = true;
                    IsEnabledProducedDate = true;
                    IsEnabledReceptionDate = true;
                }
            }
        }
        #endregion

        #region 提交 —— async void Submit()

        /// <summary>
        /// 提交
        /// </summary>
        public async void Submit()
        {
            #region # 验证

            if (this.SelectedMaterial == null)
            {
                MessageBox.Show("请选择物料定义！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (SelectedMaterial.HasLot)
            {
                if (this.SelectedSupplier == null)
                {
                    MessageBox.Show("请选择供应商！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                if (string.IsNullOrEmpty(this.ProductionBatchNo))
                {
                    MessageBox.Show("生产批次不能为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                if (string.IsNullOrEmpty(this.GuaranteePeriod.ToString()))
                {
                    MessageBox.Show("保质期不能为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                if (string.IsNullOrEmpty(this.Specification))
                {
                    MessageBox.Show("规格不能为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                if (string.IsNullOrEmpty(this.ProducedDate.ToString()))
                {
                    MessageBox.Show("生产日期不能为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                if (SelectedMaterialSourceType == null)
                {
                    MessageBox.Show("物料来源不能为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
                if (string.IsNullOrEmpty(this.ExpiredDate.ToString()))
                {
                    MessageBox.Show("过期日期不能为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return;
                }
            }
            if (string.IsNullOrEmpty(this.Quantity.ToString()))
            {
                MessageBox.Show("数量不能为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            if (string.IsNullOrEmpty(this.Sort.ToString()))
            {
                MessageBox.Show("排序不能为空！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return;
            }
            #endregion

            this.Busy();
            await base.TryCloseAsync(true);
            this.Idle();
        }
        #endregion
        #endregion
    }
}
